//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once


// FC_API

#ifndef FC_API
    #define FC_API
#endif


// FC_DEBUG

#ifndef FC_DEBUG
	#if defined(_DEBUG) || !defined(NDEBUG)
		#define FC_DEBUG 1
	#else
		#define FC_DEBUG 0
	#endif
#endif


// FC_ENABLE_ASSERT

#ifndef FC_ENABLE_ASSERT
	#ifdef FC_NO_ASSERT
		#define FC_ENABLE_ASSERT 0
	#else
		#define FC_ENABLE_ASSERT FC_DEBUG
	#endif
#endif


// FC_ENABLE_ASSERT

#ifndef FC_ASSERT
	#if FC_ENABLE_ASSERT
		#define FC_ASSERT(expression) if(!(expression)) assert_failure(#expression, __FILE__, __LINE__)
	#else
		#define FC_ASSERT(expression)
	#endif
#endif


// FC_TEMPORARY_MEMORY_ENABLED
//
// If enabled all temporary allocations will be dispatched to to user-defined
// allocate_temporary() and deallocate_temporary() functions.

#ifndef FC_TEMPORARY_MEMORY_ENABLED
    #define FC_TEMPORARY_MEMORY_ENABLED 1
#endif


// FC_ENABLE_SIZE_TRACKING

#ifndef FC_ENABLE_SIZE_TRACKING
    #define FC_ENABLE_SIZE_TRACKING FC_DEBUG
#endif



// FC_MIN_VECTOR_GROWTH
//
// minimum amount an uninitialized vector will allocate when a function is
// called that expands its capacity -- note there is a space-speed tradeoff here:
// if this value is too small then more allocations will be done, and if
// it too large then generally there will be more unused memory.
// for best results vector.reserve() should be preferred.
// example:
//
//    vector<int> vec; // never allocates
//    vec.push_back(42);
//    assert(vec.capacity() == FC_MIN_VECTOR_GROWTH);

#ifndef FC_MIN_VECTOR_GROWTH
	#define FC_MIN_VECTOR_GROWTH 4
#endif


// FC_REQUIRE_INITIALIZED_STRINGS
//
// In order to be standard compliant, c++ strings are required to
// not be null. If FC_USE_SSO_STRINGS is 0 then strings will be initialized
// to point to a global integral type, which acts as a buffer just large
// enough for the string to have a capacity of 1. It is recommended to leave
// this enabled as a drop-in replacement for std::string.

#ifndef FC_REQUIRE_INITIALIZED_STRINGS
	#define FC_REQUIRE_INITIALIZED_STRINGS 1
#endif


// FC_USE_SSO_STRINGS (Small-String Optimization)
//
// If set, instances of basic_string will use an underlying sso_allocator
// with an internal buffer of size FC_DEFAULT_STRING_BUFFER_SIZE by default,
// however this can be set as part of the string declaration. eg;
//
//   typedef basic_string< char, sso_allocator<64> > MyStringType;
//   MyStringType str = "This string is small enough that no allocation is needed."

#ifndef FC_USE_SSO_STRINGS
	#define FC_USE_SSO_STRINGS 1
#endif


// small string buffer optimization
#ifndef FC_DEFAULT_STRING_BUFFER_SIZE
	#define FC_DEFAULT_STRING_BUFFER_SIZE 20 // 32 bytes on 32-bit platforms
#endif


// FC_DEFAULT_TEMPORARY_STRING_TYPE
//
// Default string instance used internally for all known temorary strings.
// (eg.)
//   string res = strHello + " World"; (operator +)

#ifndef FC_DEFAULT_TEMPORARY_STRING_TYPE
	#define FC_DEFAULT_TEMPORARY_STRING_TYPE basic_string<char>
#endif


// default array allocator
#ifndef FC_DEFAULT_ARRAY_ALLOCATOR
	#define FC_DEFAULT_ARRAY_ALLOCATOR allocator
#endif


// default vector allocator
#ifndef FC_DEFAULT_VECTOR_ALLOCATOR
	#define FC_DEFAULT_VECTOR_ALLOCATOR fixed_allocator
#endif


// default fixed_vector allocator
#ifndef FC_DEFAULT_FIXED_VECTOR_ALLOCATOR
	#define FC_DEFAULT_FIXED_VECTOR_ALLOCATOR fixed_allocator
#endif


// default string allocator
#ifndef FC_DEFAULT_STRING_ALLOCATOR
	#if FC_USE_SSO_STRINGS
		#define FC_DEFAULT_STRING_ALLOCATOR sso_allocator<FC_DEFAULT_STRING_BUFFER_SIZE * sizeof(T)>
	#else
		#define FC_DEFAULT_STRING_ALLOCATOR fixed_allocator
	#endif
#endif


// default fixed_string allocator
#ifndef FC_DEFAULT_FIXED_STRING_ALLOCATOR
	#define FC_DEFAULT_FIXED_STRING_ALLOCATOR fixed_allocator
#endif


// default list allocator
#ifndef FC_DEFAULT_LIST_ALLOCATOR
	#define FC_DEFAULT_LIST_ALLOCATOR allocator
#endif


// default fixed_list allocator
#ifndef FC_DEFAULT_FIXED_LIST_ALLOCATOR
	#define FC_DEFAULT_FIXED_LIST_ALLOCATOR fixed_node_allocator
#endif


// default tree allocator
#ifndef FC_DEFAULT_TREE_ALLOCATOR
	#define FC_DEFAULT_TREE_ALLOCATOR allocator
#endif


// default fixed-size tree allocator
#ifndef FC_DEFAULT_FIXED_TREE_ALLOCATOR
	#define FC_DEFAULT_FIXED_TREE_ALLOCATOR fixed_node_allocator
#endif


// fc namespace
#define FC_NAMESPACE_BEGIN namespace fc {
#define FC_NAMESPACE_END }

// empty namespace declaration
FC_NAMESPACE_BEGIN
FC_NAMESPACE_END

